package binderipc

import android.os.Binder
import android.os.IBinder
import android.os.MemoryFile
import android.os.Parcel
import android.os.ParcelFileDescriptor
import android.util.Log
import fileoperation.FileOperation
import java.io.File
import java.io.FileDescriptor
import java.io.FileInputStream
import java.io.IOException

class PassValueService(parent: File) : Binder(), IPassValue {

    private val mParent = parent

    init {
        attachInterface(this, IPassValue.descriptor)

        parentFile = mParent
    }

    override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean {
        when (code) {
            IPassValue.PASS_INT_TRANSACTION -> {
                data.enforceInterface(IPassValue.descriptor)
                //写异常  写数据
                reply?.writeNoException()
                val d0 = data.readInt()
                val result = passInt(d0)
                Log.d("PassValueService", "---PassValueService---")
                //reply?.writeInt(result)
                reply?.writeValue(result)
                return true
            }
            IPassValue.PASS_STRING_TRANSACTION -> {
                data.enforceInterface(IPassValue.descriptor)
                reply?.writeNoException()
                passString("dbdsfwqef")
                reply?.writeString("12345")
                return true
            }
            IPassValue.PASS_VALUE_TRANSACTION -> {
                data.enforceInterface(IPassValue.descriptor)
                reply?.writeNoException()
                updateValue("567890")
                reply?.writeString("updatevalue")
                return true
            }
            IPassValue.TRANSACT_FILE_DESCRIPTOR_TRANSACTION -> {
                data.enforceInterface(IPassValue.descriptor)
                reply?.writeNoException()

                //val fileDescriptor = data.readFileDescriptor()
                //val fileDescriptor = data.readValue(javaClass.classLoader) as? ParcelFileDescriptor
                Log.d("PassValueService", "---ParcelFileDescriptor---:fileDescriptor == null")

                //这种方式不行
                //val pfds = ParcelFileDescriptor.createReliablePipe()
                //val pfdRead = pfds[0]
                //val pfdWrite = pfds[1]
                //transactFileDescriptor(pfdWrite)
                //reply?.writeValue(pfdRead)

                //这种方式可行
                val fileDescriptor = ParcelFileDescriptor.open(File(parentFile, "file0911.txt"), ParcelFileDescriptor.MODE_READ_ONLY)
                reply?.writeValue(fileDescriptor)
                return true
            }
            IPassValue.GET_PFD_TRANSACTION -> {
                data.enforceInterface(IPassValue.descriptor)
                reply?.writeNoException()
                val fileDescriptor = getPFD()
                reply?.writeValue(fileDescriptor)
                return true
            }
            IPassValue.PASS_VALUE_BY_ONEWAY_TRANSACTION -> {
                data.enforceInterface(IPassValue.descriptor)
                val value0 = data.readInt()
                val value1 = data.readInt()
                val result = passValueByOneWay(value0, value1)
                reply?.writeNoException()
                reply?.writeInt(result)
                return true
            }
        }
        return super.onTransact(code, data, reply, flags)
    }

    override fun asBinder(): IBinder {
        return this
    }

    override fun passInt(value: Int) : Int {
        return value * 100
    }

    override fun passString(str: String) {

    }

    override fun updateValue(strValue: String) {

    }

    override fun transactFileDescriptor(pfd: ParcelFileDescriptor?) {
        val buffer = ByteArray(1024)
        try {
            val inputStream = FileInputStream(File(parentFile, "file0911.txt"))
            val outputStream = ParcelFileDescriptor.AutoCloseOutputStream(pfd)
            var length = inputStream.read(buffer)
            while (length != -1) {
                outputStream.write(buffer, 0, length)
                length = inputStream.read(buffer)
            }
            inputStream.close()
            pfd?.close()
        } catch (ex: IOException) {
            ex.printStackTrace()
        }
    }

    override fun getPFD(): ParcelFileDescriptor? {
        val memoryFile: MemoryFile
        val bytes = FileOperation.readFile(File(mParent, "b10.jpg"))
        try {
            //创建MemoryFile对象
            memoryFile = MemoryFile("test_memory", 128 * 1024)
            //将数据写入到内存中
            memoryFile.outputStream.write(bytes)
            //通过反射获取到getFileDescriptor方法
            val method = MemoryFile::class.java.getDeclaredMethod("getFileDescriptor")
            //得到文件描述符
            val fileDescriptor = method.invoke(memoryFile) as? FileDescriptor
            //将文件描述符返回
            return ParcelFileDescriptor.dup(fileDescriptor)
        } catch (ex: Exception) {
            ex.printStackTrace()
        }
        return null
    }

    override fun passValueByOneWay(value0: Int, value1: Int): Int {
        return value0 + value1
    }

    companion object {
        private lateinit var parentFile: File

        fun asInterface(obj: IBinder?): IPassValue? {
            if (obj == null) {
                return null
            }
            val pv = obj.queryLocalInterface(IPassValue.descriptor) as? IPassValue
            if (pv != null) {
                return pv
            }
            return PassValueProxy(obj, parent = parentFile)
        }
    }

}
